package com.hivekion.workflow.controller;

import com.alibaba.fastjson.JSONObject;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.workflow.domain.vo.ProcessModelInputVo;
import com.hivekion.workflow.domain.vo.ProcessModelUpdateInputVo;
import com.hivekion.workflow.domain.vo.ScheduleVo;
import com.hivekion.workflow.service.ProTaskService;
import com.hivekion.workflow.service.ProcessDesignService;
import io.swagger.annotations.ApiParam;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/workflow/process")
public class ProcessController {

      @Autowired
      ProcessEngine processEngine;
      @Autowired
      RuntimeService runtimeService;
      @Autowired
      RepositoryService repositoryService;
      @Autowired
      ProTaskService proTaskService;
      @Autowired
      private ProcessDesignService processDesignService;

      /**
       * 注册流程
       *
       * @param file
       * @param name
       * @return
       */
      @PostMapping(value = "/deploy")
      @ResponseBody
      public Deployment deploy(
	      @ApiParam(value = "file", required = true) @RequestPart("file") MultipartFile file,
	      String name) {
	    RepositoryService repositoryService = processEngine.getRepositoryService();
	    Deployment deployment = null;
	    try {
		  deployment =
			  repositoryService
				  .createDeployment()
				  .addInputStream(file.getOriginalFilename(), file.getInputStream())
				  .name(name)
				  .deploy();
	    } catch (IOException e) {
		  e.printStackTrace();
	    }
	    return deployment;
      }

      /**
       * 中断流程
       *
       * @param processDefinitionId
       * @return
       */
      @PutMapping("/suspendProcess")
      public boolean suspendProcess(String processDefinitionId) {
	    repositoryService.suspendProcessDefinitionById(processDefinitionId);
	    return true;
      }

      /**
       * 激活流程
       *
       * @param processDefinitionId
       * @return
       */
      @PutMapping("activateProcess")
      public boolean activateProcess(String processDefinitionId) {
	    repositoryService.activateProcessDefinitionById(processDefinitionId);
	    return true;
      }

      @GetMapping("getList")
      public List<Model> getList() {
	    List<Model> list = repositoryService.createModelQuery().list();
	    return list;
      }

      @PostMapping("addModel")
      public void createModel(@RequestBody ProcessModelInputVo inputVo)
	      throws UnsupportedEncodingException {
	    processDesignService.createModel(inputVo);
	    return;
      }

      @GetMapping("getModelXml")
      public JSONObject getEditorXml(String modelId) {
	    return processDesignService.getEditorXml(modelId);
      }

      @PostMapping("saveModelXml")
      public void saveModelXml(@RequestBody ProcessModelUpdateInputVo inputVo) {
	    try {
		  processDesignService.saveModelXml(inputVo);
	    } catch (IOException ex) {
		  throw new BusinessException(500, ex.getMessage());
	    }
      }

      @GetMapping(value = "deploy")
      public String deploy(@RequestParam(name = "modelId") String modelId) throws Exception {
	    return processDesignService.deployModel(modelId);
      }

      @GetMapping(value = "getFlowElements")
      public List<FlowElement> getFlowElements(String processId) {
	    return processDesignService.getFlowElements(processId);
      }

      @PostMapping(value = "startProcess")
      public String startProcess(String defKey) {
	    ProcessDefinition def = repositoryService.getProcessDefinition(defKey);
	    //        ProcessInstance instance2=
	    // runtimeService.startProcessInstanceById(defKey,"3333",null);
	    //        ProcessInstance instance = runtimeService.startProcessInstanceByKey("", "", null);
	    ProcessInstance instance = runtimeService.startProcessInstanceById(defKey);

	    return instance.getId();
      }

      @PostMapping(value = "getChekTodo")
      public List<ScheduleVo> getChekTodo() {
	    List<Task> taskList = proTaskService.getCheckTodo("");
	    List<ScheduleVo> data = new ArrayList<>();
	    for (Task t : taskList) {
		  ScheduleVo vo = new ScheduleVo();
		  //vo.setTaskId(t.getId());
		  //vo.setProcessInstanceId(t.getProcessInstanceId());
		  //vo.setProcessType("测试");
		  //vo.setFormKey(t.getFormKey());
		  //vo.setCreateDate(t.getCreateTime());
		  //vo.setName(t.getName());
		  data.add(vo);
	    }
	    return data;
      }

      @PostMapping(value = "completeTask")
      public boolean completeTask(String taskId) {
	    proTaskService.complete(taskId);
	    return true;
      }
}
